home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / lib / python2.6 / dist-packages / jockey / backend.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-04-20  |  23.6 KB  |  718 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. '''Backend manager.
  5.  
  6. This encapsulates all services of the backend and manages all handlers.
  7. '''
  8. import logging
  9. import os
  10. import os.path as os
  11. import signal
  12. import threading
  13. import sys
  14. import gobject
  15. import dbus
  16. import dbus.service as dbus
  17. import dbus.mainloop.glib as dbus
  18. from oslib import OSLib
  19. import detection
  20. import xorg_driver
  21. DBUS_BUS_NAME = 'com.ubuntu.DeviceDriver'
  22.  
  23. class UnknownHandlerException(dbus.DBusException):
  24.     _dbus_error_name = 'com.ubuntu.DeviceDriver.UnknownHandlerException'
  25.  
  26.  
  27. class InvalidModeException(dbus.DBusException):
  28.     _dbus_error_name = 'com.ubuntu.DeviceDriver.InvalidModeException'
  29.  
  30.  
  31. class InvalidDriverDBException(dbus.DBusException):
  32.     _dbus_error_name = 'com.ubuntu.DeviceDriver.InvalidDriverDBException'
  33.  
  34.  
  35. class PermissionDeniedByPolicy(dbus.DBusException):
  36.     _dbus_error_name = 'com.ubuntu.DeviceDriver.PermissionDeniedByPolicy'
  37.  
  38.  
  39. class BackendCrashError(SystemError):
  40.     pass
  41.  
  42.  
  43. def dbus_sync_call_signal_wrapper(dbus_iface, fn, handler_map, *args, **kwargs):
  44.     '''Run a D-BUS method call while receiving signals.
  45.  
  46.     This function is an Ugly Hack\xe2\x84\xa2, since a normal synchronous dbus_iface.fn()
  47.     call does not cause signals to be received until the method returns. Thus
  48.     it calls fn asynchronously and sets up a temporary main loop to receive
  49.     signals and call their handlers; these are assigned in handler_map (signal
  50.     name \xe2\x86\x92 signal handler).
  51.     '''
  52.     global _h_reply_result, _h_exception_exc
  53.     if not hasattr(dbus_iface, 'connect_to_signal'):
  54.         return getattr(dbus_iface, fn)(*args, **kwargs)
  55.     
  56.     def _h_reply(result):
  57.         global _h_reply_result
  58.         _h_reply_result = result
  59.         loop.quit()
  60.  
  61.     
  62.     def _h_error(exception):
  63.         global _h_exception_exc
  64.         _h_exception_exc = exception
  65.         loop.quit()
  66.  
  67.     loop = gobject.MainLoop()
  68.     _h_reply_result = None
  69.     _h_exception_exc = None
  70.     kwargs['reply_handler'] = _h_reply
  71.     kwargs['error_handler'] = _h_error
  72.     kwargs['timeout'] = 86400
  73.     for signame, sighandler in handler_map.iteritems():
  74.         dbus_iface.connect_to_signal(signame, sighandler)
  75.     
  76.     dbus_iface.get_dbus_method(fn)(*args, **kwargs)
  77.     loop.run()
  78.     if _h_exception_exc:
  79.         raise _h_exception_exc
  80.     _h_exception_exc
  81.     return _h_reply_result
  82.  
  83.  
  84. def polkit_auth_wrapper(fn, *args, **kwargs):
  85.     '''Function call wrapper for PolicyKit authentication.
  86.  
  87.     Call fn(*args, **kwargs). If it fails with a PermissionDeniedByPolicy
  88.     and the caller can authenticate to get the missing privilege, the PolicyKit
  89.     authentication agent is called, and the function call is attempted again.
  90.  
  91.     This function also translates DBusExceptions into the Exceptions defined
  92.     above.
  93.     '''
  94.     
  95.     try:
  96.         
  97.         try:
  98.             return fn(*args, **kwargs)
  99.         except dbus.DBusException:
  100.             e = None
  101.             if e._dbus_error_name == PermissionDeniedByPolicy._dbus_error_name:
  102.                 (priv, auth_result) = str(e).split()[-2:]
  103.                 if auth_result.startswith('auth_'):
  104.                     pk_auth = dbus.Interface(dbus.SessionBus().get_object('org.freedesktop.PolicyKit.AuthenticationAgent', '/', False), 'org.freedesktop.PolicyKit.AuthenticationAgent')
  105.                     res = pk_auth.ObtainAuthorization(priv, dbus.UInt32(0), dbus.UInt32(os.getpid()), timeout = 300)
  106.                     if res:
  107.                         return fn(*args, **kwargs)
  108.                 
  109.                 raise PermissionDeniedByPolicy(priv + ' ' + auth_result)
  110.             e._dbus_error_name == PermissionDeniedByPolicy._dbus_error_name
  111.             raise 
  112.  
  113.     except dbus.DBusException:
  114.         e = None
  115.         if e._dbus_error_name == InvalidModeException._dbus_error_name:
  116.             raise InvalidModeException(str(e))
  117.         e._dbus_error_name == InvalidModeException._dbus_error_name
  118.         if e._dbus_error_name == UnknownHandlerException._dbus_error_name:
  119.             raise UnknownHandlerException(str(e))
  120.         e._dbus_error_name == UnknownHandlerException._dbus_error_name
  121.         if e._dbus_error_name == 'org.freedesktop.DBus.Python.SystemError':
  122.             raise SystemError(str(e))
  123.         e._dbus_error_name == 'org.freedesktop.DBus.Python.SystemError'
  124.         if e._dbus_error_name == 'org.freedesktop.DBus.Error.NoReply':
  125.             raise BackendCrashError
  126.         e._dbus_error_name == 'org.freedesktop.DBus.Error.NoReply'
  127.         raise 
  128.  
  129.  
  130.  
  131. class Backend(dbus.service.Object):
  132.     '''Backend manager.
  133.  
  134.     This encapsulates all services of the backend and manages all handlers. It
  135.     is implemented as a dbus.service.Object, so that it can be called through
  136.     D-BUS as well (on the /DeviceDriver object path).
  137.     '''
  138.     DBUS_INTERFACE_NAME = 'com.ubuntu.DeviceDriver'
  139.     
  140.     def __init__(self, handler_dir = None, detect = True):
  141.         '''Initialize backend (no hardware/driver detection).
  142.  
  143.         In order to be fast and not block client side applications for very
  144.         long, detect can be set to False; in that case this constructor does
  145.         not detect hardware and drivers, and client-side applications must call
  146.         detect() at program start.
  147.         '''
  148.         self.handler_dir = handler_dir
  149.         self.handler_pool = { }
  150.         self.hardware = None
  151.         self.dbus_info = None
  152.         self.polkit = None
  153.         self.enforce_polkit = True
  154.         self._package_operation_in_progress = False
  155.         if detect:
  156.             self.detect()
  157.         
  158.  
  159.     
  160.     def detect(self, sender = None, conn = None):
  161.         '''Detect available hardware and handlers.
  162.  
  163.         This method can take pretty long, so it should be called asynchronously
  164.         with a large (or indefinite) timeout, and client UIs should display a
  165.         bouncing progress bar (if appropriate). If the backend is already
  166.         initialized, this returns immediately.
  167.  
  168.         This must be called once at client-side program start.
  169.         '''
  170.         self._reset_timeout()
  171.         self._check_polkit_privilege(sender, conn, 'com.ubuntu.devicedriver.info')
  172.         if not self.hardware:
  173.             self.hardware = detection.get_hardware()
  174.             self.driver_dbs = [
  175.                 detection.LocalKernelModulesDriverDB(),
  176.                 detection.OpenPrintingDriverDB()]
  177.             self._detect_handlers()
  178.         
  179.  
  180.     detect = dbus.service.method(DBUS_INTERFACE_NAME, in_signature = '', out_signature = '', sender_keyword = 'sender', connection_keyword = 'conn')(detect)
  181.     
  182.     def available(self, mode = 'any', sender = None, conn = None):
  183.         '''List available driver IDs.
  184.         
  185.         Mode can be "any" (default) to return all available drivers, or
  186.         "free"/"nonfree" to select by license.
  187.         '''
  188.         self._reset_timeout()
  189.         self._check_polkit_privilege(sender, conn, 'com.ubuntu.devicedriver.info')
  190.         if mode == 'any':
  191.             return self.handlers.keys()
  192.         if mode not in ('free', 'nonfree'):
  193.             raise InvalidModeException('invalid mode %s: must be "free", "nonfree", or "any"' % mode)
  194.         mode not in ('free', 'nonfree')
  195.         recommended = []
  196.         nonrecommended = []
  197.         for h_id, h in self.handlers.iteritems():
  198.             if h.free() == mode == 'free':
  199.                 if h.recommended():
  200.                     recommended.append(h_id)
  201.                 else:
  202.                     nonrecommended.append(h_id)
  203.             h.recommended()
  204.         
  205.         return recommended + nonrecommended
  206.  
  207.     available = dbus.service.method(DBUS_INTERFACE_NAME, in_signature = 's', out_signature = 'as', sender_keyword = 'sender', connection_keyword = 'conn')(available)
  208.     
  209.     def get_hardware(self, sender = None, conn = None):
  210.         '''List available hardware IDs.'''
  211.         self._reset_timeout()
  212.         self._check_polkit_privilege(sender, conn, 'com.ubuntu.devicedriver.info')
  213.         return [ hwid.type + ':' + hwid.id for hwid in self.hardware ]
  214.  
  215.     get_hardware = dbus.service.method(DBUS_INTERFACE_NAME, in_signature = '', out_signature = 'as', sender_keyword = 'sender', connection_keyword = 'conn')(get_hardware)
  216.     
  217.     def handler_info(self, handler_id, sender = None, conn = None):
  218.         """Return details about a particular handler.
  219.  
  220.         The information is returned in a property_name \xe2\x86\x92 property_value
  221.         dictionary. Boolean values are encoded as 'True' and 'False' strings.
  222.         If a particular attribute is not set, it will not appear in the
  223.         dictionary.
  224.         """
  225.         self._reset_timeout()
  226.         self._check_polkit_privilege(sender, conn, 'com.ubuntu.devicedriver.info')
  227.         
  228.         try:
  229.             h = self.handlers[handler_id]
  230.         except KeyError:
  231.             raise UnknownHandlerException('Unknown handler: %s' % handler_id)
  232.  
  233.         info = {
  234.             'id': h.id(),
  235.             'name': h.name(),
  236.             'free': str(h.free()),
  237.             'enabled': str(h.enabled()),
  238.             'used': str(h.used()),
  239.             'changed': str(h.changed()),
  240.             'recommended': str(h.recommended()),
  241.             'announce': str(h.announce) }
  242.         for f in [
  243.             'description',
  244.             'rationale',
  245.             'can_change']:
  246.             v = getattr(h, f)()
  247.             if v:
  248.                 info[f] = v
  249.                 continue
  250.         
  251.         for f in [
  252.             'package',
  253.             'repository',
  254.             'driver_vendor',
  255.             'version',
  256.             'license']:
  257.             v = getattr(h, f)
  258.             if v:
  259.                 info[f] = v
  260.                 continue
  261.         
  262.         return info
  263.  
  264.     handler_info = dbus.service.method(DBUS_INTERFACE_NAME, in_signature = 's', out_signature = 'a{ss}', sender_keyword = 'sender', connection_keyword = 'conn')(handler_info)
  265.     
  266.     def handler_files(self, handler_id, sender = None, conn = None):
  267.         '''Return list of files installed by a handler.'''
  268.         
  269.         try:
  270.             h = self.handlers[handler_id]
  271.         except KeyError:
  272.             raise UnknownHandlerException('Unknown handler: %s' % handler_id)
  273.  
  274.         if not (h.package) or not h.enabled():
  275.             return []
  276.         
  277.         try:
  278.             return OSLib.inst.package_files(h.package)
  279.         except ValueError:
  280.             not h.enabled()
  281.             not h.enabled()
  282.             return []
  283.  
  284.  
  285.     handler_files = dbus.service.method(DBUS_INTERFACE_NAME, in_signature = 's', out_signature = 'as', sender_keyword = 'sender', connection_keyword = 'conn')(handler_files)
  286.     
  287.     def set_enabled(self, handler_id, enable, sender = None, conn = None):
  288.         '''Enable or disable a driver.
  289.  
  290.         This enables (enable=True) or disables (enable=False) the given Driver
  291.         ID. Return True if the handler could be activated immediately, or False
  292.         if the system needs a reboot for the changes to become effective.
  293.         '''
  294.         self._reset_timeout()
  295.         self._check_polkit_privilege(sender, conn, 'com.ubuntu.devicedriver.install')
  296.         
  297.         try:
  298.             h = self.handlers[handler_id]
  299.         except KeyError:
  300.             raise UnknownHandlerException('Unknown handler: %s' % handler_id)
  301.  
  302.         if enable:
  303.             f = h.enable
  304.         else:
  305.             f = h.disable
  306.         if not conn:
  307.             return f()
  308.         if h.package:
  309.             if enable:
  310.                 self.install_progress('download', -1, -1)
  311.             else:
  312.                 self.remove_progress(-1, -1)
  313.         
  314.         
  315.         def _f_result_wrapper():
  316.             
  317.             try:
  318.                 self._f_result = f()
  319.             except:
  320.                 self._f_exception = sys.exc_info()
  321.  
  322.  
  323.         self._f_exception = None
  324.         t_f = threading.Thread(None, _f_result_wrapper, 'thread_enable_disable', [], { })
  325.         t_f.start()
  326.         while True:
  327.             t_f.join(0.2)
  328.             if not t_f.isAlive():
  329.                 break
  330.             
  331.             if not self._package_operation_in_progress:
  332.                 if enable:
  333.                     self.install_progress('install', -1, -1)
  334.                 else:
  335.                     self.remove_progress(-1, -1)
  336.             enable
  337.         if self._f_exception:
  338.             raise self._f_exception[0], self._f_exception[1], self._f_exception[2]
  339.         self._f_exception
  340.         return self._f_result
  341.  
  342.     set_enabled = dbus.service.method(DBUS_INTERFACE_NAME, in_signature = 'sb', out_signature = 'b', sender_keyword = 'sender', connection_keyword = 'conn')(set_enabled)
  343.     
  344.     def new_used_available(self, mode = 'any', sender = None, conn = None):
  345.         '''Check for newly used or available drivers since last call.
  346.         
  347.         Return (new_used, new_avail) with lists of new drivers which are in
  348.         use, and new drivers which got available but are disabled.
  349.         Mode can be "any" (default) to return all available drivers, or
  350.         "free"/"nonfree" to select by license.
  351.         '''
  352.         self._reset_timeout()
  353.         self._check_polkit_privilege(sender, conn, 'com.ubuntu.devicedriver.check')
  354.         if mode not in ('any', 'free', 'nonfree'):
  355.             raise InvalidModeException('invalid mode %s: must be "free", "nonfree", or "any"' % mode)
  356.         mode not in ('any', 'free', 'nonfree')
  357.         seen = set()
  358.         used = set()
  359.         if os.path.exists(OSLib.inst.check_cache):
  360.             f = open(OSLib.inst.check_cache)
  361.             for line in f:
  362.                 
  363.                 try:
  364.                     (flag, h) = line.split(None, 1)
  365.                     h = unicode(h, 'UTF-8')
  366.                 except ValueError:
  367.                     logging.error('invalid line in %s: %s', OSLib.inst.check_cache, line)
  368.  
  369.                 if flag == 'seen':
  370.                     seen.add(h.strip())
  371.                     continue
  372.                 if flag == 'used':
  373.                     used.add(h.strip())
  374.                     continue
  375.                 logging.error('invalid flag in %s: %s', OSLib.inst.check_cache, line)
  376.             
  377.             f.close()
  378.         
  379.         new_avail = []
  380.         new_used = []
  381.         for h_id, h in self.handlers.iteritems():
  382.             if (mode == 'free' or not h.free() or mode == 'nonfree') and h.free():
  383.                 continue
  384.             
  385.             if h_id not in seen:
  386.                 new_avail.append(h_id)
  387.                 logging.debug('handler %s previously unseen', h_id)
  388.             
  389.             if h_id not in used and h.used():
  390.                 new_used.append(h_id)
  391.                 logging.debug('handler %s previously unused', h_id)
  392.                 continue
  393.         
  394.         logging.debug('writing back check cache %s', OSLib.inst.check_cache)
  395.         seen.update(new_avail)
  396.         used.update(new_used)
  397.         f = open(OSLib.inst.check_cache, 'w')
  398.         for s in seen:
  399.             print >>f, 'seen', s
  400.         
  401.         for u in used:
  402.             print >>f, 'used', u
  403.         
  404.         f.close()
  405.         for h_id in new_avail + []:
  406.             
  407.             try:
  408.                 if self.handlers[h_id].enabled():
  409.                     logging.debug('%s is already enabled or not available, not announcing', h_id)
  410.                     new_avail.remove(h_id)
  411.             continue
  412.             except ValueError:
  413.                 continue
  414.                 continue
  415.             
  416.  
  417.         
  418.         return (new_used, new_avail)
  419.  
  420.     new_used_available = dbus.service.method(DBUS_INTERFACE_NAME, in_signature = 's', out_signature = '(asas)', sender_keyword = 'sender', connection_keyword = 'conn')(new_used_available)
  421.     
  422.     def check_composite(self, sender = None, conn = None):
  423.         '''Check for a composite-enabling X.org driver.
  424.  
  425.         If one is available and not enabled, return its ID, otherwise return
  426.         an empty string.
  427.         '''
  428.         self._reset_timeout()
  429.         self._check_polkit_privilege(sender, conn, 'com.ubuntu.devicedriver.info')
  430.         for h_id, h in self.handlers.iteritems():
  431.             if isinstance(h, xorg_driver.XorgDriverHandler) and h.enables_composite():
  432.                 if h.enabled():
  433.                     logging.debug('Driver "%s" is already enabled and supports the composite extension.' % h.name())
  434.                     return ''
  435.                 return h_id
  436.             h.enables_composite()
  437.         
  438.         return ''
  439.  
  440.     check_composite = dbus.service.method(DBUS_INTERFACE_NAME, in_signature = '', out_signature = 's', sender_keyword = 'sender', connection_keyword = 'conn')(check_composite)
  441.     
  442.     def add_driverdb(self, db_class, db_args, sender = None, conn = None):
  443.         '''Add driver DB.
  444.  
  445.         db_class is a DriverDB class name; db_args are its constructor
  446.         arguments. If there is an error instantiating the driver DB, an
  447.         InvalidDriverDBException is thrown.
  448.         '''
  449.         
  450.         try:
  451.             cls = getattr(detection, db_class)
  452.         except AttributeError:
  453.             e = None
  454.             raise InvalidDriverDBException(str(e))
  455.  
  456.         
  457.         try:
  458.             inst = cls(*db_args)
  459.         except Exception:
  460.             e = None
  461.             raise InvalidDriverDBException(str(e))
  462.  
  463.         logging.debug('add_driverdb: Adding %s', str(inst))
  464.         self.driver_dbs.append(inst)
  465.         for h in detection.get_db_handlers(self, inst, self.hardware):
  466.             self.handlers[h.id()] = h
  467.         
  468.  
  469.     add_driverdb = dbus.service.method(DBUS_INTERFACE_NAME, in_signature = 'sas', out_signature = '', sender_keyword = 'sender', connection_keyword = 'conn')(add_driverdb)
  470.     
  471.     def update_driverdb(self, sender = None, conn = None):
  472.         '''Query driver DBs for updates.'''
  473.         self._reset_timeout()
  474.         self._check_polkit_privilege(sender, conn, 'com.ubuntu.devicedriver.update')
  475.         for db in self.driver_dbs:
  476.             logging.debug('update_driverdb: updating %s', db.__class__)
  477.             db.update(self.hardware)
  478.         
  479.         self._detect_handlers()
  480.  
  481.     update_driverdb = dbus.service.method(DBUS_INTERFACE_NAME, in_signature = '', out_signature = '', sender_keyword = 'sender', connection_keyword = 'conn')(update_driverdb)
  482.     
  483.     def search_driver(self, hwid, sender = None, conn = None):
  484.         '''Search drivers matching a HardwareID.
  485.  
  486.         This also finds drivers for hardware which is not present locally and
  487.         thus checks all the driver DBs again.
  488.  
  489.         Mode can be "any" (default) to return all available drivers, or
  490.         "free"/"nonfree" to select by license.
  491.         '''
  492.         self._reset_timeout()
  493.         self._check_polkit_privilege(sender, conn, 'com.ubuntu.devicedriver.info')
  494.         (t, i) = hwid.split(':', 1)
  495.         hardware_id = detection.HardwareID(t, i)
  496.         recommended = []
  497.         nonrecommended = []
  498.         for db in self.driver_dbs:
  499.             db.update([
  500.                 hardware_id])
  501.         
  502.         handlers = detection.get_handlers(self, self.driver_dbs, hardware = [
  503.             hardware_id], hardware_only = True)
  504.         for h in handlers:
  505.             id = h.id()
  506.             if id not in self.handlers:
  507.                 self.handlers[id] = h
  508.             
  509.             if h.recommended():
  510.                 recommended.append(id)
  511.                 continue
  512.             nonrecommended.append(id)
  513.         
  514.         return recommended + nonrecommended
  515.  
  516.     search_driver = dbus.service.method(DBUS_INTERFACE_NAME, in_signature = 's', out_signature = 'as', sender_keyword = 'sender', connection_keyword = 'conn')(search_driver)
  517.     
  518.     def install_progress(self, phase, curr, total):
  519.         """Report package installation progress.
  520.  
  521.         'phase' is 'download' or 'install'. current and/or total might be -1 if
  522.         time cannot be determined.
  523.         """
  524.         return False
  525.  
  526.     install_progress = dbus.service.signal(DBUS_INTERFACE_NAME)(install_progress)
  527.     
  528.     def remove_progress(self, curr, total):
  529.         '''Report package removal progress.
  530.  
  531.         current and/or total might be -1 if time cannot be determined.
  532.         '''
  533.         return False
  534.  
  535.     remove_progress = dbus.service.signal(DBUS_INTERFACE_NAME)(remove_progress)
  536.     
  537.     def install_package(self, package):
  538.         '''Install software package.'''
  539.         if OSLib.inst.package_installed(package):
  540.             return None
  541.         self._package_operation_in_progress = True
  542.         if not hasattr(self, '_locations') or self.install_progress:
  543.             pass
  544.         OSLib.inst.install_package(package, None)
  545.         if OSLib.inst.package_installed(package):
  546.             self._update_installed_packages([
  547.                 package], [])
  548.         
  549.         self._package_operation_in_progress = False
  550.  
  551.     
  552.     def remove_package(self, package):
  553.         '''Remove software package.'''
  554.         if not OSLib.inst.package_installed(package):
  555.             return None
  556.         self._package_operation_in_progress = True
  557.         if not hasattr(self, '_locations') or self.remove_progress:
  558.             pass
  559.         OSLib.inst.remove_package(package, None)
  560.         if not OSLib.inst.package_installed(package):
  561.             self._update_installed_packages([], [
  562.                 package])
  563.         
  564.         self._package_operation_in_progress = False
  565.  
  566.     
  567.     def run_dbus_service(self, timeout = None, send_usr1 = False):
  568.         '''Run D-BUS server.
  569.  
  570.         If no timeout is given, the server will run forever, otherwise it will
  571.         return after the specified number of seconds.
  572.  
  573.         If send_usr1 is True, this will send a SIGUSR1 to the parent process
  574.         once the server is ready to take requests.
  575.         '''
  576.         dbus.service.Object.__init__(self, self.bus, '/DeviceDriver')
  577.         main_loop = gobject.MainLoop()
  578.         self._timeout = False
  579.         if timeout:
  580.             
  581.             def _t():
  582.                 main_loop.quit()
  583.                 return True
  584.  
  585.             gobject.timeout_add(timeout * 1000, _t)
  586.         
  587.         if send_usr1:
  588.             os.kill(os.getppid(), signal.SIGUSR1)
  589.         
  590.         while not self._timeout:
  591.             if timeout:
  592.                 self._timeout = True
  593.             
  594.             main_loop.run()
  595.  
  596.     
  597.     def create_dbus_server(klass, session_bus = False, handler_dir = None):
  598.         '''Return a D-BUS server backend instance.
  599.  
  600.         Normally this connects to the system bus. Set session_bus to True to
  601.         connect to the session bus (for testing). 
  602.         
  603.         The created backend does not yet have hardware and drivers detected,
  604.         thus clients need to call detect().
  605.         '''
  606.         import dbus.mainloop.glib as dbus
  607.         backend = Backend(handler_dir, detect = False)
  608.         dbus.mainloop.glib.DBusGMainLoop(set_as_default = True)
  609.         if session_bus:
  610.             backend.bus = dbus.SessionBus()
  611.             backend.enforce_polkit = False
  612.         else:
  613.             backend.bus = dbus.SystemBus()
  614.         backend.dbus_name = dbus.service.BusName(DBUS_BUS_NAME, backend.bus)
  615.         return backend
  616.  
  617.     create_dbus_server = classmethod(create_dbus_server)
  618.     
  619.     def create_dbus_client(klass, session_bus = False):
  620.         '''Return a client-side D-BUS interface for Backend.
  621.  
  622.         Normally this connects to the system bus. Set session_bus to True to
  623.         connect to the session bus (for testing).
  624.         '''
  625.         dbus.mainloop.glib.DBusGMainLoop(set_as_default = True)
  626.         if session_bus:
  627.             bus = dbus.SessionBus()
  628.         else:
  629.             bus = dbus.SystemBus()
  630.         obj = bus.get_object(DBUS_BUS_NAME, '/DeviceDriver')
  631.         return dbus.Interface(obj, Backend.DBUS_INTERFACE_NAME)
  632.  
  633.     create_dbus_client = classmethod(create_dbus_client)
  634.     
  635.     def _update_installed_packages(self, add, remove):
  636.         '''Update backup_dir/installed_packages list of driver packages.
  637.         
  638.         This keeps a log of all packages that jockey installed for supporting
  639.         drivers, so that distribution installers on live CDs can push them into
  640.         the installed system as well.
  641.  
  642.         add and remove are lists which package names to add/remove from it.
  643.         '''
  644.         current = set()
  645.         path = os.path.join(OSLib.inst.backup_dir, 'installed_packages')
  646.         if os.path.exists(path):
  647.             for line in open(path):
  648.                 line = line.strip()
  649.                 if line:
  650.                     current.add(line)
  651.                     continue
  652.             
  653.         
  654.         current = current.union(add).difference(remove)
  655.         if current:
  656.             f = open(path, 'w')
  657.             for p in current:
  658.                 print >>f, p
  659.             
  660.             f.close()
  661.         elif os.path.exists(path):
  662.             os.unlink(path)
  663.         
  664.  
  665.     
  666.     def _detect_handlers(self):
  667.         '''Detect available handlers and their state.
  668.         
  669.         This initializes self.handlers as id \xe2\x86\x92 Handler map.'''
  670.         self.handlers = { }
  671.         for h in detection.get_handlers(self, self.driver_dbs, handler_dir = self.handler_dir, hardware = self.hardware):
  672.             self.handlers[h.id()] = h
  673.         
  674.  
  675.     
  676.     def _reset_timeout(self):
  677.         '''Reset the D-BUS server timeout.'''
  678.         self._timeout = False
  679.  
  680.     
  681.     def _check_polkit_privilege(self, sender, conn, privilege):
  682.         '''Verify that sender has a given PolicyKit privilege.
  683.  
  684.         sender is the sender\'s (private) D-BUS name, such as ":1:42"
  685.         (sender_keyword in @dbus.service.methods). conn is
  686.         the dbus.Connection object (connection_keyword in
  687.         @dbus.service.methods). privilege is the PolicyKit privilege string.
  688.  
  689.         This method returns if the caller is privileged, and otherwise throws a
  690.         PermissionDeniedByPolicy exception.
  691.         '''
  692.         if sender is None and conn is None:
  693.             return None
  694.         if not self.enforce_polkit:
  695.             return None
  696.         pid = self.dbus_info.GetConnectionUnixProcessID(sender)
  697.         if self.polkit is None:
  698.             self.polkit = dbus.Interface(dbus.SystemBus().get_object('org.freedesktop.PolicyKit', '/', False), 'org.freedesktop.PolicyKit')
  699.         
  700.         
  701.         try:
  702.             res = self.polkit.IsProcessAuthorized(privilege, pid, True)
  703.         except dbus.DBusException:
  704.             e = None
  705.             if e._dbus_error_name == 'org.freedesktop.DBus.Error.ServiceUnknown':
  706.                 self.polkit = None
  707.                 return self._check_polkit_privilege(sender, conn, privilege)
  708.             raise 
  709.         except:
  710.             e._dbus_error_name == 'org.freedesktop.DBus.Error.ServiceUnknown'
  711.  
  712.         if res != 'yes':
  713.             logging.debug('_check_polkit_privilege: sender %s on connection %s pid %i requested %s: %s' % (sender, conn, pid, privilege, res))
  714.             raise PermissionDeniedByPolicy(privilege + ' ' + res)
  715.         res != 'yes'
  716.  
  717.  
  718.